home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / Key / KeyCodes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-10  |  29.1 KB  |  1,256 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     keycodes.c
  5.  
  6.     DESCRIPTION
  7.     Lowlevel module for evaluation of keycodes and qualifiers
  8.  
  9.     NOTES
  10.     highly amiga - specific
  11.  
  12.     BUGS
  13.     no use of dead-keys
  14.  
  15.     TODO
  16.     deadkey - checking
  17.     qual2iqual
  18.  
  19.     EXAMPLES
  20.  
  21.     SEE ALSO
  22.  
  23.     INDEX
  24.  
  25.     HISTORY
  26.     14-Dez-92 b_null created
  27.     14-Jan-93 b_null added UP
  28.     15-Jan-92 b_null added DeadKeyConvert, removed exit_kb - it caused a GURU
  29.     04 Apr 93 b_null added QUAL_PR*, QUAL_NLK, QUAL_REP; renamed USHORT,UBYTE->TQUAL,TCODE
  30.     30 Apr 93 b_null added is_rawc
  31.     16 Jun 93 b_null introduced "struct keyspec"
  32.     29-Jun-94 b_null Docs updated
  33.     03-Jul-94 b_null Added "DoubleClick-Key"
  34.  
  35. ******************************************************************************/
  36.  
  37. /**************************************
  38.         Includes
  39. **************************************/
  40. #define  KEY_INTERNAL
  41. #include "defs.h"
  42. #include <devices/keymap.h>
  43. #include <devices/console.h>
  44. #include <clib/utility_protos.h>
  45. extern struct Library *UtilityBase;
  46. #include <pragmas/utility_pragmas.h>
  47. #ifdef PATCH_NULL
  48. #include "AUTO.h"
  49. #else
  50. #define MK_AUTOINIT(x) void x (void)
  51. #endif /*  */
  52.  
  53. extern UBYTE CtlC;
  54.  
  55.  
  56.  
  57. /**************************************
  58.         Globale Variable
  59. **************************************/
  60.  
  61. Prototype struct Library * ConsoleDevice;
  62. struct Library * ConsoleDevice = NULL;
  63.  
  64. /**************************************
  65.       Interne Defines & Strukturen
  66. **************************************/
  67. typedef struct IOStdReq CIO;
  68.  
  69.  
  70. /* format of entries in lname[] */
  71. #define LN(a,b,c,d)  ((a<<24)|(b<<16)|(c<<8)|d)
  72.  
  73. /* important numbers in lname[] */
  74. #define F1_START  0           /* Function keys */
  75. #define SP_START 10           /* special keys    */
  76. #define CS_START 20           /* cursor keys    */
  77. #define N0_START 24           /* NK numbers    */
  78. #define NS_START N0_START+10   /* NK specials    */
  79. #define MB_START 41           /* Mouse     */
  80.  
  81.  
  82. /* internal representation for qualifiers */
  83. #define QUAL_SHIFT   0x0001 /* ANY SHIFT */
  84. #define QUAL_CTRL    0x0002 /* CONTROL     */
  85. #define QUAL_AMIGA   0x0004 /* ANY AMIGA */
  86. #define QUAL_ALT     0x0008 /* ANY ALT     */
  87. #define QUAL_LMB     0x0010 /* LEFT MOUSE BUTTON   */
  88. #define QUAL_MMB     0x0020 /* MIDDLE MOUSE BUTTON */
  89. #define QUAL_RMB     0x0040 /* RIGHT MOUSE BUTTON  */
  90.  
  91. #define QUAL_UP      0x0080 /* RELEASE - currently this MUST be 0x80 - that value is used in im.Code */
  92.  
  93. #define QUAL_XTX     0x0100 /* Extended Qualifiers for multi-key strokes - Removed after each keypress */
  94. #define QUAL_XTY     0x0200
  95. #define QUAL_XTZ     0x0400
  96.  
  97. #define QUAL_REP     0x0800 /* REPEAT */
  98.  
  99. #define QUAL_PRX     0x1000 /* Permanent Extended Qualifiers for multi-key strokes */
  100. #define QUAL_PRY     0x2000
  101. #define QUAL_PRZ     0x4000
  102.  
  103. #define QUAL_NLK     0x8000 /* NUMLOCK - refers only to numeric keypad */
  104.  
  105.  
  106. /* additional pseudo-intuition qualifiers - referring to the Quals above */
  107. #define EXTQUALIFIER_X    0x00100000
  108. #define EXTQUALIFIER_Y    0x00200000
  109. #define EXTQUALIFIER_Z    0x00400000
  110.  
  111. #define EXTQUALIFIER_NLK 0x0800000
  112.  
  113. #define PERQUALIFIER_X    0x01000000
  114. #define PERQUALIFIER_Y    0x02000000
  115. #define PERQUALIFIER_Z    0x04000000
  116.  
  117. #define EXTQUALIFIER_UP 0x00800000 /* this one is not used yet - the key-up information is part of ie.keyCode */
  118.  
  119.  
  120. /* some hardcoded ( I hope ) keys on Amiga Keyboard */
  121. #define CSPC  0x40 /* Spacebar    */
  122. #define CB_S  0x41 /* BackSpace */
  123. #define CENT  0x43 /* Enter    */
  124. #define CRET  0x44 /* Return    */
  125.  
  126.  
  127. /**************************************
  128.         Interne Variable
  129. **************************************/
  130. static UBYTE ctoa[128];    /* code to ascii  */
  131. static UBYTE cstoa[128];   /* code shifted to ascii */
  132.  
  133. static TQUAL qualignore[128]; /* which key ignores to which qualifier by default */ /* PATCH_NULL [04 Apr 1993] : added */
  134. static UBYTE is_rawc[128];    /* which key can be used in a DeadKeyConversion */    /* PATCH_NULL [30 Apr 1993] : added */
  135.  
  136. static ULONG lname[] =
  137. {
  138.     /* FuncKeys */
  139.     LN('f','1', 0 , 0  ), LN('f','2', 0 , 0  ), LN('f','3', 0 , 0  ),
  140.     LN('f','4', 0 , 0  ), LN('f','5', 0 , 0  ), LN('f','6', 0 , 0  ),
  141.     LN('f','7', 0 , 0  ), LN('f','8', 0 , 0  ), LN('f','9', 0 , 0  ),
  142.     LN('f','1','0', 0  ),
  143.     /* Specials */
  144.     LN('h','e','l', 0  ), LN('e','s','c', 0  ), LN('d','e','l', 0  ),
  145.     LN('b','a','c', 0  ), LN('b','s', 0 , 0  ), LN('t','a','b', 0  ),
  146.     LN('r','e','t',CRET), LN('e','n','t',CENT), LN('s','p','c',CSPC),
  147.     LN('s','p','a',CSPC),
  148.     /* Cursor */
  149.     LN('u','p', 0 , 0  ), LN('d','o','w', 0  ), LN('r','i','g', 0  ),
  150.     LN('l','e','f', 0  ),
  151.     /* Numeric digits */
  152.     LN('n','k','0', 0  ), LN('n','k','1', 0  ), LN('n','k','2', 0  ),
  153.     LN('n','k','3', 0  ), LN('n','k','4', 0  ), LN('n','k','5', 0  ),
  154.     LN('n','k','6', 0  ), LN('n','k','7', 0  ), LN('n','k','8', 0  ),
  155.     LN('n','k','9', 0  ),
  156.     /* Numeric Specials */
  157.     LN('n','k', 0 , 0  ), LN('n','k', 0 , 0  ), LN('n','k','/', 0  ),
  158.     LN('n','k','*', 0  ), LN('n','k','+', 0  ), LN('n','k','-', 0  ),
  159.     LN('n','k','.', 0  ),
  160.     /* Mouse Buttons */
  161.     LN('l','m','b',0x68), LN('m','m','b',0x6A), LN('r','m','b',0x69),
  162.     LN('m','m','o',0x6B),
  163.     /* /* WARNING - THESE VALUES MIGHT INTERFERE WITH OTHER KEYS */
  164.     LN('l','m','2',0x67), LN('l','m','3',0x66), LN('l','m','4',0x65),
  165.     LN('m','m','2',0x64), LN('m','m','3',0x63), LN('m','m','4',0x62),
  166.     LN('r','m','2',0x61), LN('r','m','3',0x60), LN('r','m','4',0x5f)
  167.     /* /* WARNING - THESE VALUES MIGHT INTERFERE WITH OTHER KEYS */
  168. };
  169.  
  170.  
  171.  
  172. /**************************************
  173.        Interne Prototypes
  174. **************************************/
  175.  
  176.  
  177. /*****************************************************************************
  178.  
  179.     NAME
  180.     keyboard_init
  181.  
  182.     PARAMETER
  183.     void
  184.  
  185.     RESULT
  186.     -/-
  187.  
  188.     RETURN
  189.     void
  190.  
  191.     DESCRIPTION
  192.     initializes the variables used in the current Module
  193.  
  194.     NOTES
  195.     That functon MUST be called before any other call to any
  196.     other functions of the key-modules
  197.  
  198.     BUGS
  199.     if a dead- and a deadable-key are next to each other,
  200.     tables might get corrupted (but I cannot imagine that)
  201.  
  202.     EXAMPLES
  203.  
  204.     SEE ALSO
  205.  
  206.     INTERNALS
  207.  
  208.     HISTORY
  209.     14-Dec-92  b_null included & modified
  210.  
  211. ******************************************************************************/
  212.  
  213. Prototype void keyboard_init (void);
  214.  
  215. void keyboard_init (void)
  216. {
  217.     static struct InputEvent ievent = {
  218.     NULL,
  219.     IECLASS_RAWKEY,
  220.     0, 0, 0, NULL,          /* 0,0 */ /* time */
  221.     };
  222.     UBYTE buf[32];
  223.     short i,   /* TCODE */
  224.       len; /* short */
  225.  
  226. /* printf ("keyboard_init\n"); */
  227. /*    clrmem (qualignore, sizeof (qualignore)); */ /* PATCH_NULL [04 Apr 1993] : added */
  228.  
  229.     /* ---- Init unshifted keys (ctoa) */
  230.     /*        together w/ longkeys and is_rawc */
  231.  
  232.     ievent.ie_Qualifier        = 0;
  233.     ievent.ie_position.ie_addr = NULL;
  234.     for (i = 0; i < 128; ++i) {
  235.     ievent.ie_Code = i;
  236.  
  237.     len = RawKeyConvert (&ievent, buf, 32, NULL);
  238.  
  239.     qualignore[i] = QUAL_NLK; /* PATCH_NULL [04 Apr 1993] : added */
  240.     is_rawc[i] = (len > 0);   /* PATCH_NULL [30 Apr 1993] : added */
  241.  
  242.     switch(len) {
  243.     case 1:     /*    ESC/DEL/BS/TAB/NKx  */
  244.         if ((buf[0] & 0x7F) >= 32 && (buf[0] & 0x7F) < 127)
  245.         ctoa[i] = buf[0];
  246.  
  247.         switch(buf[0]) {
  248.         case 0x1B:    lname[SP_START+1] |= i; break;
  249.         case 0x7F:    lname[SP_START+2] |= i; break;
  250.         case 0x08:    lname[SP_START+3] |= i;
  251.             lname[SP_START+4] |= i; break;
  252.         case 0x09:    lname[SP_START+5] |= i; break;
  253.         case '@':                                                           /* for setmap cdn     */
  254.         case '[':                                                           /* for setmap d,f,i,n */
  255.         case '(': if (i > 0x3A) lname[NS_START+0] |= LN(0,0,*buf,i); qualignore[i] &= ~QUAL_NLK; break; /* for setmap usa/gb  */
  256.         case '°':                                                           /* for setmap cdn     */
  257.         case ']':                                                           /* for setmap d,i,f,n */
  258.         case ')': if (i > 0x3A) lname[NS_START+1] |= LN(0,0,*buf,i); qualignore[i] &= ~QUAL_NLK; break; /* for setmap usa/gb  */
  259.         case '/': if (i > 0x3A) lname[NS_START+2] |= i; qualignore[i] &= ~QUAL_NLK; break;
  260.         case '*': if (i > 0x3A) lname[NS_START+3] |= i; qualignore[i] &= ~QUAL_NLK; break;
  261.         case '+': if (i > 0x3A) lname[NS_START+4] |= i; qualignore[i] &= ~QUAL_NLK; break;
  262.         case '-': if (i > 0x3A) lname[NS_START+5] |= i; qualignore[i] &= ~QUAL_NLK; break;
  263.         case '.': if (i > 0x3A) lname[NS_START+6] |= i; qualignore[i] &= ~QUAL_NLK; break;
  264.         default:
  265.         if (i >= 0x0F && isdigit (buf[0])) {
  266.             lname[N0_START+buf[0]-'0'] |= i;
  267.             qualignore[i] &= ~QUAL_NLK; /* PATCH_NULL [04 Apr 1993] : added */
  268.         } /* if */
  269.         } /* switch */
  270.         break;
  271.  
  272.     case 2:     /*    cursor            */
  273.         if (buf[0] == 0x9B) {
  274.  
  275.         switch(buf[1]) {
  276.         case 0x41:  lname[CS_START+0] |= i;  break;
  277.         case 0x42:  lname[CS_START+1] |= i;  break;
  278.         case 0x43:  lname[CS_START+2] |= i;  break;
  279.         case 0x44:  lname[CS_START+3] |= i;  break;
  280.         } /* switch */
  281.  
  282.         } /* if */
  283.         break;
  284.  
  285.     case 3:     /*    function/help        */
  286.         if (buf[0] == 0x9B && buf[2] == 0x7E) {
  287.  
  288.         if (buf[1] == 0x3F)
  289.             lname[SP_START+0] |= i;
  290.         if (buf[1] >= 0x30 && buf[1] <= 0x39)
  291.             lname[buf[1]-0x30+F1_START] |= i;
  292.  
  293.         } /* if */
  294.         break;
  295.     } /* switch */
  296.     } /* for */
  297.  
  298.     /* ---- init Shifted Keys (cstoa) */
  299.  
  300.     ievent.ie_Qualifier        = IEQUALIFIER_LSHIFT;
  301.     ievent.ie_position.ie_addr = NULL;
  302.     for (i = 0; i < 128; ++i) {
  303.     ievent.ie_Code = i;
  304.  
  305.     len = RawKeyConvert (&ievent,buf,32,NULL);
  306.  
  307.     if (len == 1)
  308.         cstoa[i] = buf[0];
  309.     } /* for */
  310.  
  311.     /* ---- calc CtlC - Code */
  312.  
  313.     {
  314.     struct keyspec ks;
  315.  
  316.     get_codequal ("c", &ks);
  317.  
  318.     CtlC = KS_CODE(&ks);
  319.     } /* block */
  320. } /* keyboard_init */
  321.  
  322.  
  323.  
  324. /*****************************************************************************
  325.  
  326.     NAME
  327.     cqtoa
  328.  
  329.     PARAMETER
  330.     KEYSPEC *ks
  331.  
  332.     RESULT
  333.     a ptr to the string that is the readable
  334.     form of that key-stroke (static)
  335.  
  336.     RETURN
  337.     UBYTE *
  338.  
  339.     DESCRIPTION
  340.  
  341.     NOTES
  342.     we return a ptr to a static array of char
  343.     for only use of Qualifiers simply use KS_CODE(ks) == -1
  344.  
  345.     BUGS
  346.     (none known)
  347.  
  348.     EXAMPLES
  349.  
  350.     SEE ALSO
  351.  
  352.     INTERNALS
  353.  
  354.     HISTORY
  355.     14-Dez-92 b_null created
  356.     14-Jan-93 b_null added UP
  357.     04 Apr 93 b_null added REP,NLK,PER*
  358.     16 Jun 93 b_null introduced "struct keyspec"
  359.     29-Jun-94 b_null changed Types
  360.  
  361. ******************************************************************************/
  362.  
  363. Prototype UBYTE* cqtoa (KEYSPEC *ks);
  364.  
  365. UBYTE *cqtoa (KEYSPEC *ks)
  366. {
  367.     static UBYTE buf[32];
  368.     UBYTE    *ptr = buf;
  369.     int      i;
  370.  
  371.     /* ---- Build Qual part */
  372.  
  373.     if (KS_QUAL(ks) & QUAL_SHIFT)
  374.     *ptr++ = 's';
  375.     if (KS_QUAL(ks) & QUAL_CTRL)
  376.     *ptr++ = 'c';
  377.     if (KS_QUAL(ks) & QUAL_ALT)
  378.     *ptr++ = 'a';
  379.     if (KS_QUAL(ks) & QUAL_AMIGA)
  380.     *ptr++ = 'A';
  381.     if (KS_QUAL(ks) & QUAL_LMB)
  382.     *ptr++ = 'L';
  383.     if (KS_QUAL(ks) & QUAL_MMB)
  384.     *ptr++ = 'M';
  385.     if (KS_QUAL(ks) & QUAL_RMB)
  386.     *ptr++ = 'R';
  387.  
  388.     if (KS_QUAL(ks) & QUAL_XTX)
  389.     *ptr++ = 'x';
  390.     if (KS_QUAL(ks) & QUAL_XTY)
  391.     *ptr++ = 'y';
  392.     if (KS_QUAL(ks) & QUAL_XTZ)
  393.     *ptr++ = 'z';
  394.  
  395.     if (KS_QUAL(ks) & QUAL_PRX)
  396.     *ptr++ = 'X';
  397.     if (KS_QUAL(ks) & QUAL_PRY)
  398.     *ptr++ = 'Y';
  399.     if (KS_QUAL(ks) & QUAL_PRZ)
  400.     *ptr++ = 'Z';
  401.  
  402.     if (KS_QUAL(ks) & QUAL_NLK)
  403.     *ptr++ = 'n';
  404.     if (KS_QUAL(ks) & QUAL_REP)
  405.     *ptr++ = 'r';
  406.     if (KS_QUAL(ks) & QUAL_UP)
  407.     *ptr++ = 'u';
  408. /*
  409. **  --- That little fragment was added
  410. **    to be able to get the extended qualifiers with already existing functions
  411. **    U might uncomment it, if U wanna get information about
  412. **    which quals have been set with QUALIFIER
  413. */
  414.     if (KS_CODE(ks) == (-1)) {
  415. /* printf("U used a wrong undef\n"); */
  416.     *ptr = 0;
  417.     return(buf); /* do not append a code-value */
  418.     } /* if */
  419.  
  420.     /* ---- Append the '-' between Qual & Code */
  421.  
  422.     /* if (KS_QUAL(ks)) */       /* commented out for better readable keyfiles */
  423.     *ptr++ = '-';
  424.  
  425.     /* ---- Try it as a Long Name */
  426.  
  427.     for (i = 0; i < sizeof(lname)/sizeof(lname[0]); ++i) {
  428.     if ((lname[i]&0xFF) == KS_CODE(ks)) {
  429.         *ptr++ = (lname[i]>>24);
  430.         *ptr++ = (lname[i]>>16);
  431.         *ptr++ = (lname[i]>>8);
  432.         break;
  433.     } /* if */
  434.     } /* for */
  435.  
  436.     if (i == sizeof(lname)/sizeof(lname[0])) {
  437.  
  438.     /* ---- Try it as a normal Code */
  439.  
  440.     *ptr = ctoa[KS_CODE(ks)];
  441.  
  442.     if (*ptr) {
  443.         ptr ++;
  444.     /* PATCH_NULL [14 Feb 1993] : direct access to rawcodes ... */
  445.     } else {
  446.  
  447.         /* ---- Try it as a HexValue */
  448.  
  449.         sprintf (ptr, "0x%02x",KS_CODE(ks));
  450.         ptr += 4;
  451.     } /* if */
  452.     /* PATCH_NULL [14 Feb 1993] : ... direct access to rawcodes */
  453.     } /* if no spcname */
  454.  
  455.     *ptr = 0;
  456.     return buf;
  457. } /* cqtoa */
  458.  
  459.  
  460. /*****************************************************************************
  461.  
  462.     NAME
  463.     get_codequal
  464.  
  465.     PARAMETER
  466.     VAL (char *, string)
  467.     VAR (struct keyspec, ks)
  468.  
  469.     RESULT
  470.     success: TRUE == ok; FALSE == error (unknown string)
  471.  
  472.     RETURN
  473.     BOOL
  474.  
  475.     DESCRIPTION
  476.     we try to extract Qualifier- and Keycode -information
  477.     from an ascii-String and put the found values into
  478.     pcode and pqual
  479.  
  480.     NOTES
  481.     for only use of Qualifiers simply use code == -1
  482.  
  483.     BUGS
  484.     (none known)
  485.  
  486.     EXAMPLES
  487.  
  488.     SEE ALSO
  489.  
  490.     INTERNALS
  491.  
  492.     HISTORY
  493.     14-Dec-92 b_null included & modified
  494.     14-Jan-93 b_null added UP
  495.     04 Apr 93 b_null added REP,NLK,PER*
  496.     16 Jun 93 b_null introduced "struct keyspec"
  497.     29-Jun-94 b_null changed Types
  498.  
  499. ******************************************************************************/
  500.  
  501. Prototype BOOL get_codequal (const UBYTE *str, KEYSPEC *ks);
  502.  
  503. BOOL get_codequal (const UBYTE *str, KEYSPEC *ks)
  504. {
  505.     /* const char * base = str; */
  506.     TQUAL     qual;
  507.     short     i;
  508.     short     has_qual = 0;
  509.  
  510.     KS_MASK(ks) = QUALMASK;
  511.  
  512.     qual = 0;
  513.  
  514.     /* ---- Get the Qualifier */
  515.  
  516.     { /* PATCH_NULL 03-09-94 added: check _IF_ there is a qualifier */
  517.     int f=0;
  518.     const char *p = str;
  519.     while (*p) {
  520.         if (f) {
  521.         has_qual = 1;
  522.         break;
  523.         }
  524.         f = (*(p++) == '-');
  525.     }
  526.     }
  527.  
  528.     if (has_qual) {
  529.     for (; *str && (*str) && (*str != '-'); ++str) {
  530.         /* ---- Why the hell did I use IF insted of SWITCH? */
  531.         if (*str == 's')
  532.         qual |= QUAL_SHIFT;
  533.         if (*str == 'c')
  534.         qual |= QUAL_CTRL;
  535.         if (*str == 'a')
  536.         qual |= QUAL_ALT;
  537.         if (*str == 'A')
  538.         qual |= QUAL_AMIGA;
  539.         if (*str == 'L')
  540.         qual |= QUAL_LMB;
  541.         if (*str == 'M')
  542.         qual |= QUAL_MMB;
  543.         if (*str == 'R')
  544.         qual |= QUAL_RMB;
  545.  
  546.         if (*str == 'x')
  547.         qual |= QUAL_XTX;
  548.         if (*str == 'y')
  549.         qual |= QUAL_XTY;
  550.         if (*str == 'z')
  551.         qual |= QUAL_XTZ;
  552.  
  553.         if (*str == 'X')
  554.         qual |= QUAL_PRX;
  555.         if (*str == 'Y')
  556.         qual |= QUAL_PRY;
  557.         if (*str == 'Z')
  558.         qual |= QUAL_PRZ;
  559.  
  560.         if (*str == 'n')
  561.         qual |= QUAL_NLK;
  562.         if (*str == 'u')
  563.         qual |= QUAL_UP;
  564.         if (*str == 'r')
  565.         qual |= QUAL_REP;
  566.  
  567.         if (!qual) {
  568.         /* error (mal_formed_key); */
  569.         goto notqual;
  570.         }
  571.     } /* for */
  572.  
  573.     ++str;
  574.     /* PATCH_NULL 03-09-94 disabled the test, its done before */
  575.     /* ---- test if that was really a Qualified Key, and not only a LongName * /
  576.     if (*str == 0) { qual = 0; str = base; } else { ++str; } / * if */
  577.     } /* if */
  578.  
  579.     /* ---- Get the Code */
  580.  
  581. notqual:
  582.     if (strlen(str) != 1) {           /* ---- long name */
  583.     short shift = 24;
  584.     long mult = 0;
  585.     UBYTE c;
  586.     const UBYTE * ptr = str; /* PATCH_NULL [14 Feb 1993] : added */
  587.  
  588.     /* ---- create LongName-Entry */
  589.  
  590.     KS_QUAL(ks) = qual;
  591.     while ((c = *str) && shift >= 8) {
  592.         /* c = tolower (c); PATCH_NULL 06-09-94 COMMENTED OUT! */
  593.         mult |= c << shift;
  594.         shift -= 8;
  595.         ++str;
  596.     } /* while */
  597.  
  598.     /* ---- Search LongNames */
  599.  
  600.     for (i = 0; lname[i]; ++i) {
  601.         if (mult == (lname[i] & 0xFFFFFF00)) {
  602.         KS_CODE(ks) = lname[i] & 0xFF;
  603.         return TRUE;
  604.         } /* if */
  605.     } /* for */
  606.  
  607.     /* ---- Try it as a HexNumber */
  608.  
  609.     /* PATCH_NULL [14 Feb 1993] : direct access to raw-codes ... */
  610.     /* NOTE             : we cannot save that value yet!!! */
  611. /* printf ("testing %s with hex\n", str); */
  612.     if ((*ptr == '0') && ((ptr[1]|0x20) == 'x')) {
  613.         i = (strtol (ptr, &str, 0x10) & 0xff);
  614.         if (ptr != str) {
  615.         KS_CODE(ks) = i;
  616.         return TRUE;
  617.         } /* if scanned */
  618.     } /* if */
  619.     /* PATCH_NULL [14 Feb 1993] : ... direct access to raw-codes */
  620.  
  621.     } else {            /*    ---- single character keycap */
  622.  
  623.     /* ---- check the normal codes */
  624.  
  625.     for (i = 0; i < sizeof(ctoa); ++i) {
  626.         if (*str == ctoa[i]) {
  627.         KS_CODE(ks) = i;
  628.         KS_QUAL(ks) = qual;
  629.         return TRUE;
  630.         } /* if */
  631.     } /* for */
  632.  
  633.     /* ---- check the shifted codes */
  634.  
  635.     for (i = 0; i < sizeof(cstoa); ++i) {
  636.         if (*str == cstoa[i]) {
  637.         KS_CODE(ks) = i;
  638.         KS_QUAL(ks) = qual|QUAL_SHIFT;
  639.         return TRUE;
  640.         } /* if */
  641.     } /* for */
  642.     } /* if */
  643.     return FALSE;
  644. } /* get_codequal */
  645.  
  646.  
  647. /*****************************************************************************
  648.  
  649.     NAME
  650.     iqual2qual
  651.  
  652.     PARAMETER
  653.     ULONG  iqual
  654.     int    blen
  655.     char * buf
  656.     int    code ; TCODE code ?
  657.  
  658.     RESULT
  659.     the [X]DME-internal qualifier referred by the intuition qualifier qual;
  660.  
  661.     RETURN
  662.     TQUAL
  663.  
  664.     DESCRIPTION
  665.     transform the different intuition - Qualifiers to [X]DME-Qualifiers
  666.     (if we have caps-lock and buffer contains
  667.     one lower char, it is used like shift)
  668.  
  669.     NOTES
  670.  
  671.     BUGS
  672.     (none known)
  673.  
  674.     EXAMPLES
  675.  
  676.     SEE ALSO
  677.  
  678.     INTERNALS
  679.  
  680.     HISTORY
  681.     14-Dec-92 b_null included & modified
  682.     14-Jan-93 b_null added UP
  683.     04 Apr 93 b_null added REP,NLK,PER*
  684.     29-Jun-94 b_null changed Types
  685.  
  686. ******************************************************************************/
  687.  
  688. Prototype TQUAL iqual2qual (ULONG qual, int blen, char * buf, int code);
  689.  
  690. TQUAL iqual2qual (ULONG iqual, int blen, char * buf, int code) /* (unsigned long iqual, int blen, char * buf, TCODE code) */
  691. {
  692.     TQUAL q2 = 0;
  693.  
  694.     if (iqual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  695.     q2 |= QUAL_SHIFT;
  696.     if (iqual & (IEQUALIFIER_CONTROL))
  697.     q2 |= QUAL_CTRL;
  698.     if (iqual & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
  699.     q2 |= QUAL_AMIGA;
  700.     if (iqual & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
  701.     q2 |= QUAL_ALT;
  702.  
  703. /* We should replace "isalpha(buf[1])" by "((buf[1] != ToUpper(buf[1])) || (buf[1] != ToLower(buf[1])))"    */
  704. /* Thats much longer, ok, but that way we can be sure to use a real uppercase character, also for non-Ascii */
  705. /* an alternative was to check for the reverse - MapANSI(&buf[1],1,&buf[4], 1) and then check for */
  706. /* a SHIFT-qual in our result */
  707.  
  708.     if (!(q2 & QUAL_SHIFT))
  709.     /* if ((iqual & IEQUALIFIER_CAPSLOCK) && blen == 1 && isalpha (buf[1])) */
  710.     if ((iqual & IEQUALIFIER_CAPSLOCK) && (blen == 1) && (isalpha (buf[1]) || ((buf[1] != ToUpper(buf[1])) || (buf[1] != ToLower(buf[1]))))) /* PATCH_NULL 27-09-93 */
  711.         q2 |= QUAL_SHIFT;
  712.  
  713.     if (iqual & IEQUALIFIER_LEFTBUTTON)
  714.     q2 |= QUAL_LMB;
  715.     if (iqual & IEQUALIFIER_MIDBUTTON)
  716.     q2 |= QUAL_MMB;
  717.     if (iqual & (IEQUALIFIER_RBUTTON))
  718.     q2 |= QUAL_RMB;
  719.  
  720.     if (iqual & (EXTQUALIFIER_X))
  721.     q2 |= QUAL_XTX;
  722.     if (iqual & (EXTQUALIFIER_Y))
  723.     q2 |= QUAL_XTY;
  724.     if (iqual & (EXTQUALIFIER_Z))
  725.     q2 |= QUAL_XTZ;
  726.  
  727.     if (iqual & (PERQUALIFIER_X))
  728.     q2 |= QUAL_PRX;
  729.     if (iqual & (PERQUALIFIER_Y))
  730.     q2 |= QUAL_PRY;
  731.     if (iqual & (PERQUALIFIER_Z))
  732.     q2 |= QUAL_PRZ;
  733.  
  734.     if (iqual & (EXTQUALIFIER_NLK))
  735.     q2 |= QUAL_NLK;
  736.     if (iqual & (IEQUALIFIER_REPEAT))
  737.     q2 |= QUAL_REP;
  738.  
  739. #if 0
  740.     if (iqual & (EXTQUALIFIER_UP))
  741.     q2 |= QUAL_UP;
  742.     q2 |= (QUAL_UP & code);
  743. #endif
  744.  
  745.     if (code & 0x080)
  746.     q2 |= QUAL_UP;
  747.  
  748.     return q2;
  749. } /* iqual2qual */
  750.  
  751.  
  752. /*****************************************************************************
  753.  
  754.     NAME
  755.     qual2iqual
  756.  
  757.     PARAMETER
  758.     TQUAL qual ; might be changed to KEYSPEC
  759.  
  760.     RESULT
  761.     Intuition Qualifiers, which represent the [X]DME - qualifiers
  762.  
  763.     RETURN
  764.     ULONG
  765.  
  766.     DESCRIPTION
  767.     simple transformation of internal representation for
  768.     Qualifiers to a possible Amiga-representation
  769.  
  770.     NOTES
  771.     very slow
  772.     !ATTN!    there is currently no possibility to
  773.         transform the UP-Qualifier
  774.  
  775.     BUGS
  776.     QUAL_UP is not supported (we needed a Code for it)
  777.  
  778.     EXAMPLES
  779.  
  780.     SEE ALSO
  781.     iqual2qual
  782.  
  783.     INTERNALS
  784.  
  785.     HISTORY
  786.     14-Dez-92 b_null created
  787.     14-Jan-93 b_null added UP
  788.     04 Apr 93 b_null added REP,NLK,PER*
  789.     29-Jun-94 b_null changed Types
  790.  
  791. ******************************************************************************/
  792.  
  793. Prototype ULONG qual2iqual (TQUAL qual);
  794.  
  795. ULONG qual2iqual (TQUAL qual)
  796. {
  797.     ULONG iq2 = 0;
  798.  
  799.     if (qual & QUAL_XTX)
  800.     iq2 |= EXTQUALIFIER_X;
  801.     if (qual & QUAL_XTY)
  802.     iq2 |= EXTQUALIFIER_Y;
  803.     if (qual & QUAL_XTZ)
  804.     iq2 |= EXTQUALIFIER_Z;
  805.  
  806.     if (qual & QUAL_PRX)
  807.     iq2 |= PERQUALIFIER_X;
  808.     if (qual & QUAL_PRY)
  809.     iq2 |= PERQUALIFIER_Y;
  810.     if (qual & QUAL_PRZ)
  811.     iq2 |= PERQUALIFIER_Z;
  812.  
  813.     if (qual & QUAL_NLK)
  814.     iq2 |= EXTQUALIFIER_NLK;
  815.     if (qual & QUAL_REP)
  816.     iq2 |= IEQUALIFIER_REPEAT;
  817. #if 0
  818.     if (qual & QUAL_UP)        /* that info must be placed into Code */
  819.     iq2 |= EXTQUALIFIER_UP;
  820. #endif
  821.  
  822.     if (qual & QUAL_SHIFT)
  823.     iq2 |= IEQUALIFIER_LSHIFT;
  824.     if (qual & QUAL_CTRL)
  825.     iq2 |= IEQUALIFIER_CONTROL;
  826.     if (qual & QUAL_AMIGA)
  827.     iq2 |= IEQUALIFIER_LCOMMAND;
  828.     if (qual & QUAL_ALT)
  829.     iq2 |= IEQUALIFIER_LALT;
  830.     if (qual & QUAL_LMB)
  831.     iq2 |= IEQUALIFIER_LEFTBUTTON;
  832.     if (qual & QUAL_MMB)
  833.     iq2 |= IEQUALIFIER_MIDBUTTON;
  834.     if (qual & QUAL_RMB)
  835.     iq2 |= IEQUALIFIER_RBUTTON;
  836.  
  837.     return iq2;
  838. } /* qual2iqual */
  839.  
  840.  
  841. /*****************************************************************************
  842.  
  843.     NAME
  844.     a2iqual
  845.  
  846.     PARAMETER
  847.     const UBYTE* str
  848.     ULONG       *piqual
  849.  
  850.     RESULT
  851.     success: TRUE == ok; FALSE == any error
  852.  
  853.     RETURN
  854.     BOOL
  855.  
  856.     DESCRIPTION
  857.     convert an ascii string into Input-Qualifiers
  858.     we check each char of the string and set the according bit
  859.     the string may be NULL-terminated or "-"-terminated
  860.     any unknown char causes "return (0)"
  861.  
  862.     NOTES
  863.  
  864.     BUGS
  865.     (none known)
  866.  
  867.     EXAMPLES
  868.  
  869.     SEE ALSO
  870.  
  871.     INTERNALS
  872.  
  873.     HISTORY
  874.     14-Dez-92 null created
  875.     14-Jan-93 b_null added UP
  876.     04 Apr 93 b_null added REP,NLK,PER*
  877.     29-Jun-94 b_null changed Types
  878.  
  879. ******************************************************************************/
  880.  
  881. Prototype BOOL a2iqual (const UBYTE *str, ULONG *piqual);
  882.  
  883. BOOL a2iqual (const UBYTE* str, ULONG *piqual)
  884. {
  885.     *piqual = 0;
  886.     for (; *str; str++) {
  887.     switch (*str) {
  888.     case 'a':   *piqual |= IEQUALIFIER_LALT;        break;
  889.     case 'A':   *piqual |= IEQUALIFIER_LCOMMAND;    break;
  890.     case 's':   *piqual |= IEQUALIFIER_LSHIFT;      break;
  891.     case 'L':   *piqual |= IEQUALIFIER_LEFTBUTTON;  break;
  892.     case 'M':   *piqual |= IEQUALIFIER_MIDBUTTON;   break;
  893.     case 'R':   *piqual |= IEQUALIFIER_RBUTTON;     break;
  894.  
  895.     case 'u':   *piqual |= EXTQUALIFIER_UP;         break;
  896.     case 'n':   *piqual |= EXTQUALIFIER_NLK;        break;
  897.     case 'r':   *piqual |= IEQUALIFIER_REPEAT;      break;
  898.  
  899.     case 'x':   *piqual |= EXTQUALIFIER_X;          break;
  900.     case 'y':   *piqual |= EXTQUALIFIER_Y;          break;
  901.     case 'z':   *piqual |= EXTQUALIFIER_Z;          break;
  902.  
  903.     case 'X':   *piqual |= PERQUALIFIER_X;          break;
  904.     case 'Y':   *piqual |= PERQUALIFIER_Y;          break;
  905.     case 'Z':   *piqual |= PERQUALIFIER_Z;          break;
  906.  
  907.     case '-':   return TRUE;
  908.     default:    return FALSE;
  909.     } /* switch */
  910.     } /* for */
  911.     return TRUE;
  912. } /* a2iqual */
  913.  
  914.  
  915. /*****************************************************************************
  916.  
  917.     NAME
  918.     iqual2a
  919.  
  920.     PARAMETER
  921.     ULONG iqual
  922.  
  923.     RESULT
  924.     the string that corresponds to iqual  (static)
  925.  
  926.     RETURN
  927.     UBYTE *
  928.  
  929.     DESCRIPTION
  930.     create a string representing the readble form of Intuition Qualifiers
  931.  
  932.     NOTES
  933.     this is a slow routine, as we do not
  934.     immediately evaluated the string, but
  935.     use iqual2qual and cqtoa (but it works :-)
  936.  
  937.     BUGS
  938.     (none known)
  939.  
  940.     EXAMPLES
  941.  
  942.     SEE ALSO
  943.     iqual2qual(), cqtoa
  944.  
  945.     INTERNALS
  946.  
  947.     HISTORY
  948.     14-Dez-92 null created
  949.     29-Jun-94 b_null changed Types
  950.  
  951. ******************************************************************************/
  952.  
  953. Prototype UBYTE *iqual2a (ULONG iqual);
  954.  
  955. UBYTE *iqual2a (ULONG iqual)
  956. {
  957.     struct keyspec ks = {0, 0, (UBYTE)~0};
  958.     KS_QUAL(&ks) = iqual2qual (iqual, 0, NULL, 0);
  959.     return (cqtoa (&ks));
  960. } /* iqual2a */
  961.  
  962.  
  963. /*****************************************************************************
  964.  
  965.     NAME
  966.     init_kb
  967.     (exit_kb - removed)
  968.  
  969.     PARAMETER
  970.     void
  971.  
  972.     RESULT
  973.     -/-
  974.  
  975.     RETURN
  976.     void
  977.  
  978.     DESCRIPTION
  979.     entry code for Keyboard Control
  980.  
  981.     NOTES
  982.     this is the lowest level on Amiga Software, we use;
  983.     exit_kb is removed, so user cannot call it any more
  984.     init_kb is "__AUTOINIT" so user need not call it
  985.     (he must indeed, if his compiler does not support __autoinit)
  986.  
  987.     BUGS
  988.     for unknown reasons, we must not close ConsoleDevice,
  989.         else the machine is going to crash
  990.  
  991.     EXAMPLES
  992.  
  993.     SEE ALSO
  994.     reset_hash
  995.  
  996.     INTERNALS
  997.     Open the Console.Device and call keyboard_init
  998.  
  999.     HISTORY
  1000.     15-Dez-92  b_null created
  1001.     15-Jan-93  b_null removed exit_kb
  1002.     29-06-94   b_null removed KC_Used
  1003.  
  1004. ******************************************************************************/
  1005.  
  1006. Prototype void init_kb (void);
  1007.  
  1008. MK_AUTOINIT( init_kb )
  1009. {
  1010.     struct IOStdReq cio;
  1011.  
  1012. /* printf ("init_kb\n"); */
  1013.  
  1014.     if (!ConsoleDevice) {
  1015.     OpenDevice ("console.device", -1, (struct IORequest *)&cio, 0);
  1016.     ConsoleDevice = (struct Library *)cio.io_Device;
  1017.     keyboard_init ();
  1018.     } /* if */
  1019. } /* init_kb */
  1020.  
  1021.  
  1022. /* FUNCTION TO BE KILLED AGAIN */
  1023.  
  1024. /*****************************************************************************
  1025.  
  1026.     NAME
  1027.     CtoA
  1028.  
  1029.     PARAMETER
  1030.     TCODE c
  1031.  
  1032.     RESULT
  1033.     ctoa[c]
  1034.  
  1035.     RETURN
  1036.     UBYTE
  1037.  
  1038.     DESCRIPTION
  1039.     this function was created to hide the stucture ctoa
  1040.  
  1041.     ctoa is designed to check, IF a KeyCode c represents a
  1042.     single ascii character and WHICH one
  1043.  
  1044.     NOTES
  1045.     a macro might be possible, too;
  1046.     but then You have to declare ctoa non-static
  1047.  
  1048.     ctoa is initialized by keyboard_init(), so
  1049.     any call to CtoA before keyboard initialisation is undefined
  1050.  
  1051.     BUGS
  1052.     none known
  1053.  
  1054.     EXAMPLES
  1055.  
  1056.     SEE ALSO
  1057.     ctoa
  1058.  
  1059.     INTERNALS
  1060.  
  1061.     HISTORY
  1062.     30-Dez-92 b_null created
  1063.     15-Jan-93 b_null documented
  1064.     29-Jun-94 b_null changed Types
  1065.  
  1066. ******************************************************************************/
  1067.  
  1068. Prototype UBYTE  CtoA (TCODE c);
  1069.  
  1070. UBYTE CtoA (TCODE c)
  1071. {
  1072.     return (ctoa[c]);
  1073. } /* CtoA */
  1074.  
  1075.  
  1076.  
  1077. #ifdef NOT_DEF     /* FUNCTION TO BE KILLED AGAIN */
  1078.  
  1079. /*****************************************************************************
  1080.  
  1081.     NAME
  1082.     CignoreQ
  1083.  
  1084.     PARAMETER
  1085.     TCODE c
  1086.  
  1087.     RESULT
  1088.     qualignore[c]
  1089.  
  1090.     RETURN
  1091.     TQUAL
  1092.  
  1093.     DESCRIPTION
  1094.     this function was created to hide the structure qualignore
  1095.  
  1096.     qualignore is designed to check, IF a KeyCode c ignores
  1097.     any [X]DME qualifiers and WHICH ones
  1098.  
  1099.     NOTES
  1100.     a macro might be possible, too;
  1101.     but then You have to declare qualignore non-static
  1102.  
  1103.     qualignore is initialized by keyboard_init(), so
  1104.     any call to CignoreQ before keyboard initialisation is undefined
  1105.  
  1106.     ***  that function is not (yet) used (any more)  ***
  1107.  
  1108.     BUGS
  1109.     none known
  1110.  
  1111.     EXAMPLES
  1112.  
  1113.     SEE ALSO
  1114.     qualignore
  1115.  
  1116.     INTERNALS
  1117.  
  1118.     HISTORY
  1119.     04 Apr 93 b_null created & documented
  1120.  
  1121. ******************************************************************************/
  1122.  
  1123. Prototype TQUAL CIgnoreQ (TCODE c);
  1124.  
  1125. TQUAL CignoreQ (TCODE c)
  1126. {
  1127.     return (qualignore[c]);
  1128. } /* CignoreQ */
  1129.  
  1130. #endif        /* FUNCTION TO BE KILLED AGAIN */
  1131.  
  1132.  
  1133. /*****************************************************************************
  1134.  
  1135.     NAME
  1136.     IsRawC
  1137.  
  1138.     PARAMETER
  1139.     KEYSPEC *ks
  1140.  
  1141.     RESULT
  1142.     is_rawc[c]
  1143.  
  1144.     RETURN
  1145.     Bool
  1146.  
  1147.     DESCRIPTION
  1148.     this function was created to hide the structure is_rawc
  1149.     lateron I added a check for QUAL_UP
  1150.  
  1151.     is_rawc is designed to check for the possibility, if
  1152.     we can use a keycode as RawKey for DeadKeyConvert or not
  1153.  
  1154.     NOTES
  1155.     a macro might be possible, too;
  1156.     but then You have to declare is_rawc non-static
  1157.  
  1158.     is_rawc is initialized by keyboard_init(), so
  1159.     any call to IsRawC before keyboard initialisation
  1160.     is undefined
  1161.  
  1162.     BUGS
  1163.     none known
  1164.  
  1165.     EXAMPLES
  1166.  
  1167.     SEE ALSO
  1168.     is_rawc
  1169.  
  1170.     INTERNALS
  1171.  
  1172.     HISTORY
  1173.     30 Apr 93 b_null created & documented
  1174.     17 Jun 93 b_null introduced "struct keyspec" , QUAL_UP-check
  1175.     27-06-94  b_null added check for QUAL_ALT/SHIFT
  1176.     29-Jun-94 b_null changed Types
  1177.  
  1178. ******************************************************************************/
  1179.  
  1180. Prototype BOOL IsRawC (KEYSPEC *ks);
  1181.  
  1182. BOOL IsRawC (KEYSPEC *ks)
  1183. {
  1184.     return (BOOL)((((is_rawc[KS_CODE(ks)] != 0) || KS_QUAL(ks) & (QUAL_SHIFT|QUAL_ALT))&& ((KS_QUAL(ks) & QUAL_UP) == 0))? TRUE: FALSE);
  1185. } /* IsRawC */
  1186.  
  1187.  
  1188. /*****************************************************************************
  1189.  
  1190.     NAME
  1191.     DeadKeyConvert
  1192.  
  1193.     PARAMETER
  1194.     struct IntuiMessage * msg
  1195.     UBYTE *           buf
  1196.     int              bufsize
  1197.     struct KeyMap *       keymap
  1198.  
  1199.     RESULT
  1200.     actual - the number of characters in the buffer, -2 if no
  1201.     RawKey was given or -1 if a buffer overflow was about to occur.
  1202.  
  1203.     RETURN
  1204.     int
  1205.  
  1206.     DESCRIPTION
  1207.     convert any RawKey-Code to (VanillaKey) an ASCII-String
  1208.  
  1209.     NOTES
  1210.     this function is only used by keycontrol.keyctl
  1211.     but it for itself uses ConsoleDevice, so I could not
  1212.     decide where to put it.
  1213.  
  1214.     BUGS
  1215.  
  1216.     EXAMPLES
  1217.  
  1218.     SEE ALSO
  1219.     console.device/RawKeyConvert
  1220.  
  1221.     INTERNALS
  1222.     erzeuge eine iorequest mit den allernotwendigsten Eintraegen
  1223.     und lasse sie auswerten
  1224.  
  1225.     HISTORY
  1226.     15-Dez-92 b_null moved to keycontrol.c
  1227.     16.Dez.92 b_null documented
  1228.     15-Jan-93 b_null moved to keycodes.c
  1229.  
  1230. ******************************************************************************/
  1231.  
  1232. Prototype int DeadKeyConvert (struct IntuiMessage * msg, UBYTE * buf, int bufsize, struct KeyMap * keymap);
  1233.  
  1234. int DeadKeyConvert (struct IntuiMessage * msg, UBYTE * buf, int bufsize, struct KeyMap * keymap)
  1235. {
  1236.     static struct InputEvent ievent = {
  1237.     NULL, IECLASS_RAWKEY
  1238.     };
  1239.  
  1240.     if (msg->Class != RAWKEY)
  1241.     return(-2);
  1242.  
  1243.     ievent.ie_Code           = msg->Code;
  1244.     ievent.ie_Qualifier        = msg->Qualifier;
  1245.     ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
  1246.  
  1247. /* printf ("DeadKeyConvert %02x + %08lx\n", msg->Code, ievent.ie_position.ie_addr); */
  1248.  
  1249.     return (RawKeyConvert (&ievent, (char *)buf, bufsize, keymap));
  1250. } /* DeadKeyConvert */
  1251.  
  1252.  
  1253. /******************************************************************************
  1254. *****  ENDE keycodes.c
  1255. ******************************************************************************/
  1256.